// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)

#ifndef UNITY_SPRITES_INCLUDED
#define UNITY_SPRITES_INCLUDED

#include "UnityCG.cginc"

#ifdef UNITY_INSTANCING_ENABLED

    UNITY_INSTANCING_BUFFER_START(PerDrawSprite)
        // SpriteRenderer.Color while Non-Batched/Instanced.
        UNITY_DEFINE_INSTANCED_PROP(fixed4, unity_SpriteRendererColorArray)
        // this could be smaller but that's how bit each entry is regardless of type
        UNITY_DEFINE_INSTANCED_PROP(fixed2, unity_SpriteFlipArray)
    UNITY_INSTANCING_BUFFER_END(PerDrawSprite)

    #define _RendererColor  UNITY_ACCESS_INSTANCED_PROP(PerDrawSprite, unity_SpriteRendererColorArray)
    #define _Flip           UNITY_ACCESS_INSTANCED_PROP(PerDrawSprite, unity_SpriteFlipArray)

#endif // instancing

CBUFFER_START(UnityPerDrawSprite)
#ifndef UNITY_INSTANCING_ENABLED
    fixed4 _RendererColor;
    fixed2 _Flip;
    fixed2 _Speed;
    fixed2 _Offset;
#endif
    float _EnableExternalAlpha;
CBUFFER_END

// Material Color.
fixed4 _Color;

struct appdata_t
{
    float4 vertex   : POSITION;
    float4 color    : COLOR;
    float2 texcoord : TEXCOORD0;
    UNITY_VERTEX_INPUT_INSTANCE_ID
};

struct v2f
{
    float4 vertex   : SV_POSITION;
    float4 vertex2   : TEXCOORD1;
    fixed4 color    : COLOR;
    float2 texcoord : TEXCOORD0;
    UNITY_VERTEX_OUTPUT_STEREO
};

inline float4 UnityFlipSprite(in float3 pos, in fixed2 flip)
{
    return float4(pos.xy * flip, pos.z, 1.0);
}

float2 CartesianToAffine(float2 cartesianPos, float2 _Origin, float2 _U, float2 _V) {
    // 计算向量PO = P - O
    float2 po = cartesianPos - _Origin;
                
    // 计算矩阵行列式
    float det = _U.x * _V.y - _U.y * _V.x;
                
    // 避免除以零（基向量不平行时行列式不为零）
    if (abs(det) < 0.0001) {
        return float2(0, 0);
    }
                
    // 计算a和b（使用克莱默法则求解线性方程组）
    float a = (po.x * _V.y - po.y * _V.x) / det;
    float b = (po.y * _U.x - po.x * _U.y) / det;
                
    return float2(a, b);
}

int _CloudTexWidth;
float2 _CloudTexOrigin;
float2 _MainTexSize;

v2f SpriteVert(appdata_t IN)
{
    v2f OUT;

    UNITY_SETUP_INSTANCE_ID (IN);
    UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);

    OUT.vertex = UnityFlipSprite(IN.vertex, _Flip);
    OUT.vertex2 = mul(UNITY_MATRIX_M, IN.vertex);
    float a = 1.96;
    float b = 0.98;

    OUT.vertex2.xy = CartesianToAffine(OUT.vertex2.xy, float2(0, 0), float2(a, b), float2(-a, b));
    //OUT.vertex2.x = floor(OUT.vertex2.x);
    //OUT.vertex2.y = floor(OUT.vertex2.y);


    OUT.vertex2.xy -= _CloudTexOrigin.xy;
    OUT.vertex2.xy += 0.5;

    OUT.vertex2.xy /= _CloudTexWidth;
    //OUT.vertex2.xy = (CartesianToAffine(OUT.vertex2.xy, float2(0, 0), float2(a, b), float2(-a, b))) / _CloudTexWidth;

    OUT.vertex = UnityObjectToClipPos(OUT.vertex);
    //OUT.texcoord = (mul(UNITY_MATRIX_M, IN.vertex) + _Time.w * _Speed.xy * 0) / _MainTexSize.xy * 100;
    OUT.texcoord = (mul(UNITY_MATRIX_M, IN.vertex) + _Time.w * _Speed.xy) / _MainTexSize.xy * 100;
    OUT.color = IN.color * _Color * _RendererColor;

    #ifdef PIXELSNAP_ON
    OUT.vertex = UnityPixelSnap (OUT.vertex);
    #endif

    return OUT;
}

sampler2D _CloudTex;

sampler2D _MainTex;
sampler2D _AlphaTex;

fixed4 SampleSpriteTexture (float2 uv)
{
    fixed4 color = tex2D (_MainTex, uv);

#if ETC1_EXTERNAL_ALPHA
    fixed4 alpha = tex2D (_AlphaTex, uv);
    color.a = lerp (color.a, alpha.r, _EnableExternalAlpha);
#endif

    return color;
}

fixed4 SpriteFrag(v2f IN) : SV_Target
{
    float2 texCoord = IN.texcoord;


    float4 cloud = tex2D (_CloudTex, IN.vertex2.xy);

    //float len = length(IN.vertex2.xy);
    //len -= 4;
    //len /= 2;
    //len = clamp(len, 0, 1);

    fixed4 c = SampleSpriteTexture (texCoord + _Offset) * IN.color;
    c.a *= cloud.a;
    //c.a = cloud.a * 0.25;
    //c.rgb = 1;

    c.rgb *= c.a;

    //c.r = cloud.a;

    return c;
}

#endif // UNITY_SPRITES_INCLUDED
